using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Schema;
using OpenComposite.Base.Collections;
using OpenComposite.Repository.Designer;
using OpenComposite.Repository.Properties;
using OpenComposite.EII.Repository;

namespace OpenComposite.EII.Designer.BUSView
{
	[ToolboxItem(false)]
	public partial class UCSubscriptionList : UserControl
	{
		#region Initialization
		public UCSubscriptionList(Workflow.WorkflowController wfController)
		{
			_wfController = wfController;
			_items = null;
			_mouseDownColumn = -1;
			_mouseDownRow = -1;
			_isDragging = false;

			InitializeComponent();
		}
		#endregion

		#region Public Members

		#region Properties
		#endregion

		#region Methods
		public void UpdateList()
		{
			this.SuspendLayout();
			fillList();
			this.ResumeLayout();
		}
		public void SetSimpleMode(bool simpleMode)
		{
			if ( _items != null ) {
				foreach ( SubscriptionItem item in _items ) {
					item.SimpleMode = simpleMode;
				}
				dgvSubscription.InvalidateColumn(colPublishedDoc.Index);
				dgvSubscription.AutoResizeColumn(colPublishedDoc.Index);
				dgvSubscription.InvalidateColumn(colSubscribedDocs.Index);
				dgvSubscription.AutoResizeColumn(colSubscribedDocs.Index);
			}
		}
		#endregion

		#endregion

		#region Private Members

		#region Variables
		private Workflow.WorkflowController _wfController;
		private SubscriptionItemList _items;
		private int _mouseDownRow;
		private int _mouseDownColumn;
		private bool _isDragging;

		#endregion

		#region Methods
		private bool SimpleMode
		{
			get
			{
				BUSViewController bvc = this._wfController.DesignerView.DesignController as BUSViewController;
				if ( bvc == null ) return false;
				else return bvc.SimpleMode;
			}
		}
		private void fillList()
		{
			if ( _items == null ) {
				_items = new SubscriptionItemList();
				bindList();
			} else {
				_items.Clear();
			}
			if ( _wfController.Workflow.BuildType == OpenComposite.EII.Repository.WorkflowBuildType.ASMX_IIS ) {
				// add process input / output to subscription list
				_items.Add(new SubscriptionItem(_wfController.Workflow));
			}

			// add logical activities to subscription list
			List<Repository.LogicalActivity> lstLogActs = _wfController.GetLogicalActivities();
			foreach ( Repository.LogicalActivity logact in lstLogActs ) {
				WorkflowEvent we = logact.GetWorkflowEvent();
				WorkflowMethod wm = logact.GetWorkflowMethod();
				Verb v = logact.Verb;
				bool addtolist = false;
				if ( ( v != null && ( v.InputBusinessObject != null || v.OutputBusinessObject != null ) ) ||
					 ( wm != null && ( wm.OutputBusinessObject != null || wm.InputBusinessObject != null ) ) ||
					 ( we != null && we.BusinessObject != null ) ||
					 ( v == null && wm == null && we == null ) ) {
					addtolist = true;
				}
				if ( addtolist ) _items.Add(new SubscriptionItem(logact));
			}
			foreach ( Repository.WorkflowField wf in _wfController.Workflow.Interface.Fields ) {
				_items.Add(new SubscriptionItem(wf));
			}
			dgvSubscription.Sort(colProcessElement, ListSortDirection.Ascending);
		}
		private void bindList()
		{
			if ( _items == null )
				throw new NullReferenceException();

			if ( dgvSubscription.DataSource == _items )
				return;

			dgvSubscription.AutoGenerateColumns = false;
			dgvSubscription.DataSource = _items;
		}
		private void doSubscriptionMapping(Repository.LogicalActivity logact)
		{
			NamedBusinessObjectCollection lstSubscribedBOs = logact.GetSubscribedBusinessObjects();
			if ( lstSubscribedBOs == null || lstSubscribedBOs.Count == 0 ) return; // EXIT

			if ( logact.InputBusinessObject == null ) {
				MessageBox.Show("This logical capability has not an input contract.", "Subscription Mapping", MessageBoxButtons.OK, MessageBoxIcon.Warning);
				return; // EXIT
			}

			Mapping.DoSubscriptionMapping(
				lstSubscribedBOs,
				logact,
				logact.InputBusinessObject);
		}
		private void doDataAggregatorMapping(Repository.LogicalActivity logact)
		{
			NamedBusinessObjectCollection lstSubscribedBOs = logact.GetSubscribedBusinessObjects();
			if ( lstSubscribedBOs == null || lstSubscribedBOs.Count == 0 ) return; // EXIT

			BusinessObject boOutput = logact.GetOutputBusinessObject();
			if ( boOutput == null || boOutput.Schema == null ) {
				MessageBox.Show("No Output Business Object Available.", "Data Aggregator Mapping", MessageBoxButtons.OK, MessageBoxIcon.Warning);
				return; // EXIT
			}
			Mapping.DoSubscriptionMapping(
				lstSubscribedBOs,
				logact,
				boOutput);

		}
		#endregion

		#region Event Handlers

		private void UCSubscriptionList_Load(object sender, EventArgs e)
		{
			//fillList();
			//_items = new SubscriptionItemList();
			//bindList();
		}

		#region Drag&Drop

		private void dgvSubscription_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
		{
			_mouseDownColumn = e.ColumnIndex;
			_mouseDownRow = e.RowIndex;
			_isDragging = false;
		}

		private void dgvSubscription_MouseUp(object sender, MouseEventArgs e)
		{
			_mouseDownColumn = -1;
			_mouseDownRow = -1;
			_isDragging = false;
		}

		private void dgvSubscription_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
		{
			if ( ( e.Button == MouseButtons.Left || e.Button == MouseButtons.Right ) &&
				 e.RowIndex >= 0 && e.ColumnIndex == colPublishedDoc.Index ) {

				if ( _isDragging || e.ColumnIndex != _mouseDownColumn || e.RowIndex != _mouseDownRow )
					return;

				// start drag if published document is available
				SubscriptionItem item = dgvSubscription.Rows[e.RowIndex].DataBoundItem as SubscriptionItem;
				if ( item != null && !string.IsNullOrEmpty(item.PublishedDoc) ) {
					dgvSubscription.DoDragDrop(item, DragDropEffects.Link);
					_isDragging = true;
				}
			}
		}

		private void dgvSubscription_DragDrop(object sender, DragEventArgs e)
		{
			_isDragging = false;
			_mouseDownColumn = -1;
			_mouseDownRow = -1;

			if ( !e.Data.GetDataPresent(typeof(SubscriptionItem)) )
				return;

			SubscriptionItem publishItem = e.Data.GetData(typeof(SubscriptionItem)) as SubscriptionItem;
			Point ptClient = dgvSubscription.PointToClient(new Point(e.X, e.Y));
			DataGridView.HitTestInfo hti = dgvSubscription.HitTest(ptClient.X, ptClient.Y);
			if ( publishItem != null && hti.RowIndex >= 0 &&
				 dgvSubscription.Rows[hti.RowIndex].DataBoundItem != publishItem ) {
				// if item != null AND current row is not the process input/outout row AND
				// current row is not the dragging row
				SubscriptionItem subscibeItem = dgvSubscription.Rows[hti.RowIndex].DataBoundItem as SubscriptionItem;
				BusinessObject publishedBO;
				if ( publishItem.WorkflowField != null ) {
					publishedBO = publishItem.WorkflowField.BusinessObject;
				} else {
					publishedBO = publishItem.PublishedBusinessObject;
				}
				if ( !subscibeItem.CanSubscribe(publishedBO) ) return;

				if ( publishItem.LogicalActivity != null ) {
					if ( subscibeItem.LogicalActivity.LogicalActivityType == LogicalActivityType.LogicalMethodCall ) {
						subscibeItem.LogicalActivity.InputVariableName =
							publishItem.LogicalActivity.OutputVariableName;
						subscibeItem.LogicalActivity.AddSubscribedBusinessObject(publishedBO, publishItem.LogicalActivity == null ? -1 : publishItem.LogicalActivity.ID);
					} else {
						foreach ( Repository.BusinessObject bo in
									publishItem.LogicalActivity.GetPublishedBusinessObjects().BusinessObjects ) {
							subscibeItem.LogicalActivity.AddSubscribedBusinessObject(bo, publishItem.LogicalActivity.ID);
						}
						if ( publishItem.LogicalActivity.OutputBusinessObject != null ) {
							subscibeItem.LogicalActivity.AddSubscribedBusinessObject(
								publishItem.LogicalActivity.OutputBusinessObject, publishItem.LogicalActivity.ID);
						}
					}
					subscibeItem.LogicalActivity.Save();
				} else if ( publishItem.Workflow != null ) {
					if ( publishItem.Workflow.InputBusinessObjectID > 0 ) {
						subscibeItem.LogicalActivity.AddSubscribedBusinessObject(
							publishItem.Workflow.InputBusinessObject, -1);
						subscibeItem.LogicalActivity.Save();
					}
				} else if ( publishItem.WorkflowField != null ) {
					subscibeItem.LogicalActivity.AddSubscribedBusinessObject(publishItem.WorkflowField.GetContainerBusinessObject(), -1);
					subscibeItem.LogicalActivity.InputVariableName = publishItem.PublishedDoc;
					subscibeItem.LogicalActivity.Save();
				} else {
					if ( publishedBO != null ) {
						subscibeItem.LogicalActivity.AddSubscribedBusinessObject(publishedBO, -1);
						subscibeItem.LogicalActivity.Save();
					}
				}
				dgvSubscription.UpdateCellValue(colSubscribedDocs.Index, hti.RowIndex);
			}
		}

		private void dgvSubscription_DragEnter(object sender, DragEventArgs e)
		{

		}

		private void dgvSubscription_DragLeave(object sender, EventArgs e)
		{

		}

		private void dgvSubscription_DragOver(object sender, DragEventArgs e)
		{
			if ( !e.Data.GetDataPresent(typeof(SubscriptionItem)) )
				return;

			SubscriptionItem item = e.Data.GetData(typeof(SubscriptionItem)) as SubscriptionItem;
			Point ptClient = dgvSubscription.PointToClient(new Point(e.X, e.Y));
			DataGridView.HitTestInfo hti = dgvSubscription.HitTest(ptClient.X, ptClient.Y);
			if ( item != null && hti.RowIndex >= 0 ) {
				SubscriptionItem subribeItem = dgvSubscription.Rows[hti.RowIndex].DataBoundItem as SubscriptionItem;
				BusinessObject publishedBO;
				if ( item.WorkflowField != null ) {
					publishedBO = item.WorkflowField.BusinessObject;
				} else {
					publishedBO = item.PublishedBusinessObject;
				}
				if ( subribeItem != item && subribeItem.CanSubscribe(publishedBO) ) {
					// if item != null AND current row is not the process input/output row AND
					// current row is not the dragging row
					e.Effect = DragDropEffects.Link;
				} else {
					e.Effect = DragDropEffects.None;
				}
			} else {
				e.Effect = DragDropEffects.None;
			}
		}

		private void dgvSubscription_GiveFeedback(object sender, GiveFeedbackEventArgs e)
		{
		}

		private void dgvSubscription_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
		{

		}

		#endregion

		#region Context Menu

		private void dgvSubscription_CellContextMenuStripNeeded(object sender, DataGridViewCellContextMenuStripNeededEventArgs e)
		{
			if ( e.RowIndex >= 0 ) {
				dgvSubscription[e.ColumnIndex, e.RowIndex].Selected = true;
				ToolStripMenuItem mi;

				// get subscription item
				SubscriptionItem item = dgvSubscription.Rows[e.RowIndex].DataBoundItem as SubscriptionItem;
				if ( item == null || item.LogicalActivity == null )
					return;

				// get subscribed documents
				NamedBusinessObjectCollection lstSubscribedBOs =
					item.LogicalActivity.GetSubscribedBusinessObjects();

				bool canDoMapping = false;
				bool canRemoveDocs = false;
				bool showIO = false;
				string textMIMapping = "Mapping...";

				if ( item != null && item.LogicalActivity != null ) {
					if ( item.LogicalActivity.LogicalActivityType == Repository.LogicalActivityType.LogicalCapability ||
						 item.LogicalActivity.LogicalActivityType == Repository.LogicalActivityType.LogicalOperation ) {
						canDoMapping = true;
						canRemoveDocs = true;
						showIO = true;
						textMIMapping = "Subscription Mapping...";
					} else if ( item.LogicalActivity.LogicalActivityType == Repository.LogicalActivityType.DataAggregator ) {
						canDoMapping = true;
						canRemoveDocs = true;
						textMIMapping = "Aggregation Mapping...";
					} else if ( item.LogicalActivity.LogicalActivityType == LogicalActivityType.Notification ) {
						canDoMapping = true;
						canRemoveDocs = true;
						textMIMapping = "Notification Configuration...";
					} else if ( item.LogicalActivity.LogicalActivityType == LogicalActivityType.LogicalMethodCall ) {
						canDoMapping = false;
						canRemoveDocs = true;
						showIO = true;
					}
				}


				if ( lstSubscribedBOs == null || lstSubscribedBOs.Count == 0 ) {
					canDoMapping = false;
					canRemoveDocs = false;
				}

				e.ContextMenuStrip = new ContextMenuStrip();

				if ( canDoMapping ) {
					// add Subscription Mapping...
					mi = new ToolStripMenuItem(textMIMapping,
											   Resources.bmp_mapping,
											   new EventHandler(this.SubscriptionMapping_Click));
					mi.ImageTransparentColor = Color.Magenta;
					mi.Tag = item;
					e.ContextMenuStrip.Items.Add(mi);
				}
				if ( showIO ) {
					e.ContextMenuStrip.Tag = item;
					if ( e.ContextMenuStrip.Items.Count > 0 ) {
						e.ContextMenuStrip.Items.Add(new ToolStripSeparator());
					}
					e.ContextMenuStrip.Items.Add("Show Input Business Object", null, new EventHandler(this.ShowInputBO_Click));
					e.ContextMenuStrip.Items.Add("Show Output Business Object", null, new EventHandler(this.ShowOutputBO_Click));
				}
				if ( e.ColumnIndex == colSubscribedDocs.Index ) {
					if ( canDoMapping ) {
						// create context menu for the subscribed documents column
						e.ContextMenuStrip.Items.Add(new ToolStripSeparator());
					}
					// add Show Schema
					mi = new ToolStripMenuItem("Show Schema...",
											   null,
											   new EventHandler(this.SubscribedDocs_ShowSchema));
					mi.Tag = item;
					e.ContextMenuStrip.Items.Add(mi);
					if ( canRemoveDocs ) {
						e.ContextMenuStrip.Items.Add(new ToolStripSeparator());

						// add Remove <Business Object>
						foreach ( NamedBusinessObject bo in lstSubscribedBOs ) {
							mi = new ToolStripMenuItem("Remove " + bo.Name,
													   Resources.ico_delete_16x.ToBitmap(),
													   new EventHandler(this.SubscribedDocs_RemoveOne));
							mi.Tag = new RemoveTag(item, bo, e.ColumnIndex, e.RowIndex);
							e.ContextMenuStrip.Items.Add(mi);
						}
						e.ContextMenuStrip.Items.Add(new ToolStripSeparator());

						// add Remove All Documents
						mi = new ToolStripMenuItem("Remove All Documents",
												   Resources.ico_delete_16x.ToBitmap(),
												   new EventHandler(this.SubscribedDocs_RemoveAll));
						mi.Tag = new RemoveTag(item, null, e.ColumnIndex, e.RowIndex);
						e.ContextMenuStrip.Items.Add(mi);
					}
				}
			}
		}
		private void SubscribedDocs_ShowSchema(object sender, EventArgs e)
		{
			Application.DoEvents();
			ToolStripMenuItem mi = sender as ToolStripMenuItem;
			if ( mi != null ) {
				SubscriptionItem item = mi.Tag as SubscriptionItem;
				if ( item != null && item.LogicalActivity != null ) {
					XmlSchema xsd = item.LogicalActivity.GetSubscribedCompoundXmlSchema();
					if ( xsd != null ) {
						XmlDocument xd = new XmlDocument();
						using ( MemoryStream ms = new MemoryStream() ) {
							xsd.Write(ms);
							ms.Position = 0;
							xd.Load(ms);
						}
						formXmlViewer frm = new formXmlViewer();
						frm.XmlDocument = xd;
						frm.ShowDialog();
					}
				}
			}
		}
		private void SubscribedDocs_RemoveOne(object sender, EventArgs e)
		{
			ToolStripMenuItem mi = sender as ToolStripMenuItem;
			if ( mi != null ) {
				RemoveTag tag = mi.Tag as RemoveTag;
				if ( tag != null && tag.Item != null && tag.BObject != null ) {
					tag.Item.LogicalActivity.RemoveSubscribedBusinessObject(tag.BObject);
					tag.Item.LogicalActivity.Save();
					dgvSubscription.UpdateCellValue(tag.ColumnIndex, tag.RowIndex);
				}
			}
		}
		private void SubscribedDocs_RemoveAll(object sender, EventArgs e)
		{
			ToolStripMenuItem mi = sender as ToolStripMenuItem;
			if ( mi != null ) {
				RemoveTag tag = mi.Tag as RemoveTag;
				if ( tag != null && tag.Item != null && tag.Item.LogicalActivity != null ) {
					DialogResult result =
						MessageBox.Show("Do you really want to remove all subscribed documents?",
										mi.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
					if ( result == DialogResult.Yes ) {
						tag.Item.LogicalActivity.SetSubscribedBusinessObjects(null);
						tag.Item.LogicalActivity.Save();
						dgvSubscription.UpdateCellValue(tag.ColumnIndex, tag.RowIndex);
					}
				}
			}
		}
		private void SubscriptionMapping_Click(object sender, EventArgs e)
		{
			Application.DoEvents();
			ToolStripMenuItem mi = sender as ToolStripMenuItem;
			if ( mi != null ) {
				SubscriptionItem item = mi.Tag as SubscriptionItem;
				if ( item != null && item.LogicalActivity != null ) {
					if ( item.LogicalActivity.LogicalActivityType == Repository.LogicalActivityType.LogicalCapability ||
						 item.LogicalActivity.LogicalActivityType == Repository.LogicalActivityType.LogicalOperation ) {
						doSubscriptionMapping(item.LogicalActivity);
					} else if ( item.LogicalActivity.LogicalActivityType == Repository.LogicalActivityType.DataAggregator ) {
						doDataAggregatorMapping(item.LogicalActivity);
					} else if ( item.LogicalActivity.LogicalActivityType == LogicalActivityType.Notification ) {
						Helpers.ConfigNotification(_wfController.Workflow, item.LogicalActivity);
					}
				}
			}
		}

		private void ShowInputBO_Click(object sender, EventArgs e)
		{
			Application.DoEvents();
			ToolStripMenuItem mi = sender as ToolStripMenuItem;
			if ( mi != null ) {
				SubscriptionItem item = mi.Owner.Tag as SubscriptionItem;
				if ( item != null && item.LogicalActivity != null && item.LogicalActivity.InputBusinessObject != null ) {
					Helpers.ShowBusinessObjectTree(item.LogicalActivity.InputBusinessObject,
						string.Format("{0} (Input of {1})", item.LogicalActivity.InputBusinessObject.Name, item.Name));
				}
			}
		}
		private void ShowOutputBO_Click(object sender, EventArgs e)
		{
			Application.DoEvents();
			ToolStripMenuItem mi = sender as ToolStripMenuItem;
			if ( mi != null ) {
				SubscriptionItem item = mi.Owner.Tag as SubscriptionItem;
				if ( item != null && item.LogicalActivity != null && item.LogicalActivity.OutputBusinessObject != null ) {
					Helpers.ShowBusinessObjectTree(item.LogicalActivity.OutputBusinessObject,
						string.Format("{0} (Output of {1})", item.LogicalActivity.OutputVariableName, item.Name));
				}
			}
		}

		#endregion

		#endregion


		#endregion
	}

	#region Class: SubscriptionItemList : SearchableSortableBindingList<SubscriptionItem>
	public class SubscriptionItemList : BindingListEx<SubscriptionItem>
	{
	}
	#endregion

	#region Class: SubscriptionItem
	public class SubscriptionItem
	{
		public SubscriptionItem()
		{
			_logact = null;
			_workflow = null;
			_wfField = null;
			SimpleMode = true;
		}
		public SubscriptionItem(Repository.LogicalActivity logact)
			: this()
		{
			_logact = logact;
		}
		public SubscriptionItem(Repository.Workflow workflow)
			: this()
		{
			_workflow = workflow;
		}
		public SubscriptionItem(Repository.WorkflowField wfField)
			: this()
		{
			_wfField = wfField;
		}

		private readonly Repository.LogicalActivity _logact;
		private readonly Repository.Workflow _workflow;
		private readonly Repository.WorkflowField _wfField;

		public Repository.LogicalActivity LogicalActivity
		{
			get { return _logact; }
		}
		public Repository.Workflow Workflow
		{
			get { return _workflow; }
		}
		public Repository.WorkflowField WorkflowField
		{
			get { return _wfField; }
		}
		public bool SimpleMode { get; internal set; }

		public Image Image
		{
			get
			{
				if ( _logact != null ) {
					return _logact.Image;
				} else if ( _workflow != null ) {
					Bitmap bmp = _workflow.Image as Bitmap;
					bmp.MakeTransparent(Color.Magenta);
					return bmp;
				} else if ( _wfField != null ) {
					Bitmap bmp = _wfField.Image as Bitmap;
					bmp.MakeTransparent(Color.Magenta);
					return bmp;
				} else {
					return null;
				}
			}
		}
		public string Name
		{
			get
			{
				if ( _logact != null ) {
					return _logact.DisplayName.IfNullOrEmpty(_logact.Name);
					//Repository.Verb v = _logact.GetAssignedVerb();
					//return v != null ? v.Name : _logact.Name;
				} else if ( _workflow != null ) {
					return _workflow.StartName;
				} else if ( _wfField != null ) {
					return "Process Variable";
				} else {
					return "INVALID ITEM";
				}
			}
		}
		public string PublishedDoc
		{
			get
			{
				if ( _logact != null && _logact.HasOutputBusinessObject && _logact.OutputBusinessObject != null ) {
					return this.SimpleMode ? _logact.OutputBusinessObject.Name : _logact.OutputVariableName;
					//return _logact.OutputBusinessObject.Name;
				} else if ( _workflow != null && _workflow.InputBusinessObjectID > 0 ) {
					return _workflow.InputBusinessObject.Name;
				} else if ( _wfField != null ) {
					Repository.BusinessObject bo = _wfField.GetContainerBusinessObject();
					if ( bo == null ) {
						_wfField.CreateContainerBusinessObject();
						bo = _wfField.GetContainerBusinessObject();
					}
					if ( bo != null ) {
						return _wfField.BusinessObject != null && this.SimpleMode ? _wfField.BusinessObject.Name : bo.Name;
					} else {
						return null;
					}
				} else {
					return null;
				}
			}
		}
		public string SubscribedDocs
		{
			get
			{
				string str = "";
				if ( _logact != null ) {
					NamedBusinessObjectCollection lstBOs = _logact.GetSubscribedBusinessObjects();
					if ( lstBOs != null ) {
						foreach ( NamedBusinessObject item in lstBOs ) {
							if ( !string.IsNullOrEmpty(str) )
								str += "; ";
							str += this.SimpleMode ? item.BusinessObject.Name : item.Name;
						}
					}
				} else if ( _workflow != null && _workflow.OutputBusinessObjectID > 0 ) {
					str = _workflow.OutputBusinessObject.Name;
				}
				return str;
			}
		}

		public Repository.BusinessObject PublishedBusinessObject
		{
			get
			{
				if ( this.LogicalActivity != null ) {
					NamedBusinessObjectCollection lstBOs = this.LogicalActivity.GetPublishedBusinessObjects();
					if ( lstBOs != null && lstBOs.Count > 0 ) {
						return lstBOs[0].BusinessObject;
					}
					if ( this.LogicalActivity.OutputBusinessObject != null ) {
						return this.LogicalActivity.OutputBusinessObject;
					}
				}
				if ( this.Workflow != null ) {
					if ( this.Workflow.InputBusinessObjectID > 0 ) {
						return this.Workflow.InputBusinessObject;
					}
				}
				if ( this.WorkflowField != null ) {
					Repository.BusinessObject bo = this.WorkflowField.GetContainerBusinessObject();
					if ( bo == null ) {
						this.WorkflowField.CreateContainerBusinessObject();
						bo = this.WorkflowField.GetContainerBusinessObject();
					}
					return bo;
				}
				return null;
			}
		}

		public bool CanSubscribe(Repository.BusinessObject publishedBObject)
		{
			if ( this.LogicalActivity == null ) return false; // EXIT
			if ( this.LogicalActivity.VerbID > 0 ||
				 this.LogicalActivity.LogicalActivityType == LogicalActivityType.DataAggregator ||
				 this.LogicalActivity.LogicalActivityType == LogicalActivityType.Notification ) {
				return true; // EXIT
			}
			if ( this.LogicalActivity.WorkflowMethodID > 0 &&
				 this.LogicalActivity.InputBusinessObject != null &&
				 this.LogicalActivity.InputBusinessObject == publishedBObject ) {
				return true; // EXIT
			}
			return false;
		}
	}
	#endregion

	#region Class: RemoveTag
	internal class RemoveTag
	{
		public RemoveTag(SubscriptionItem item, NamedBusinessObject bo,
							int columnIndex, int rowIndex)
		{
			this.BObject = bo;
			this.Item = item;
			this.ColumnIndex = columnIndex;
			this.RowIndex = rowIndex;
		}
		public NamedBusinessObject BObject;
		public SubscriptionItem Item;
		public int ColumnIndex;
		public int RowIndex;
	}
	#endregion
}
